package com.mikufufu.blog.security.handler;

import com.mikufufu.blog.common.constant.ContentType;
import com.mikufufu.blog.common.constant.HttpStatus;
import com.mikufufu.blog.common.entity.AjaxResult;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 认证失败处理类，用于处理未认证的请求，返回未授权的响应。
 * 
 */
@Slf4j
@Component
public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint {

    /**
     * 当访问受保护的资源时，如果用户未通过认证，会调用此方法。
     * @param request HttpServletRequest对象，代表客户端的HTTP请求。
     * @param response HttpServletResponse对象，用于向客户端发送响应。
     * @param authException 认证异常，封装了认证失败的详细信息。
     * @throws IOException 如果在写入响应时发生IO错误。
     */
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
        // 设置响应内容类型为JSON，并使用UTF-8编码
        response.setContentType(ContentType.JSON_UTF8);

        // 记录认证失败的日志
        log.error("请求访问：{}，认证失败，无法访问系统资源", request.getRequestURI());

        // 将认证失败的信息封装为JSON格式，并写入响应体中
        response.getWriter().write(JSON.toJSONString(AjaxResult.error(HttpStatus.UNAUTHORIZED, "认证失败，无法访问系统资源")));
    }
}

